/*
avr-gcc -DF_CPU=16000000UL -mmcu=atmega328p -o sounds.out sounds.c
avr-objcopy -O ihex -R .eeprom sounds.out sounds.hex
avrdude -b57600 -patmega328p -cstk500v1 -P/dev/ttyUSB0 -U flash:w:sounds.hex
*/

#include <avr/io.h>


uint16_t delay2(uint16_t ms) {
   uint16_t i,j;
   uint16_t loop = F_CPU / 17000;  
   for (i=0;i<ms;i++) {
      for (j=0;j<loop;j++);
   }
   return ms;
}

uint16_t  musicNote(char *note)
{
	if (strcmp(note, "lowc") == 0)				return 130;
	else if(strcmp(note, "lowcsharp") == 0)		return 139;
	else if(strcmp(note, "lowdflat") == 0)		return 139;
	else if(strcmp(note, "lowd") == 0)			return 147;
	else if(strcmp(note, "lowdsharp") == 0)		return 156;
	else if(strcmp(note, "loweflat") == 0)		return 156;
	else if(strcmp(note, "lowe") == 0)			return 165;
	else if(strcmp(note, "lowf") == 0)			return 175;
	else if(strcmp(note, "lowfsharp") == 0)		return 185;
	else if(strcmp(note, "lowgflat") == 0)		return 185;
	else if(strcmp(note, "lowg") == 0)			return 196;
	else if(strcmp(note, "lowgsharp") == 0)		return 208;
	else if(strcmp(note, "lowaflat") == 0)		return 208;
	else if(strcmp(note, "lowa") == 0)			return 220;
	else if(strcmp(note, "lowasharp") == 0)		return 233;
	else if(strcmp(note, "lowbflat") == 0)		return 233;
	else if(strcmp(note, "lowb") == 0)			return 247;
	else if(strcmp(note, "midc") == 0)			return 262;
	else if(strcmp(note, "midcsharp") == 0)		return 262;
	else if(strcmp(note, "middflat") == 0)		return 277;
	else if(strcmp(note, "midd") == 0)			return 294;
	else if(strcmp(note, "middsharp") == 0)		return 311;
	else if(strcmp(note, "mideflat") == 0)		return 311;
	else if(strcmp(note, "mide") == 0)			return 330;
	else if(strcmp(note, "midf") == 0)			return 350;
	else if(strcmp(note, "midfsharp") == 0)		return 370;
	else if(strcmp(note, "midgflat") == 0)		return 370;
	else if(strcmp(note, "midg") == 0)			return 392;
	else if(strcmp(note, "midgsharp") == 0)		return 416;
	else if(strcmp(note, "midaflat") == 0)		return 416;
	else if(strcmp(note, "mida") == 0)			return 440;
	else if(strcmp(note, "midasharp") == 0)		return 466;
	else if(strcmp(note, "midbflat") == 0)		return 466;
	else if(strcmp(note, "midb") == 0)			return 494;
	else if(strcmp(note, "highc") == 0)			return 523;
	else if(strcmp(note, "highcsharp") == 0)	return 555;
	else if(strcmp(note, "highdflat") == 0)		return 555;
	else if(strcmp(note, "highd") == 0)			return 587;
	else if(strcmp(note, "highdsharp") == 0)	return 623;
	else if(strcmp(note, "higheflat") == 0)		return 623;
	else if(strcmp(note, "highe") == 0)			return 660;
	else if(strcmp(note, "highf") == 0)			return 699;
	else if(strcmp(note, "highfsharp") == 0)	return 740;
	else if(strcmp(note, "highgflat") == 0)		return 740;
	else if(strcmp(note, "highg") == 0)			return 784;
	else if(strcmp(note, "highgsharp") == 0)	return 831;
	else if(strcmp(note, "highaflat") == 0)		return 831;
	else if(strcmp(note, "higha") == 0)			return 880;
	else if(strcmp(note, "highasharp") == 0)	return 924;
	else if(strcmp(note, "highbflat") == 0)		return 924;
	else if(strcmp(note, "highb") == 0)			return 988;	
	else if(strcmp(note, "highc") == 0) 		return 523;
	else if(strcmp(note, "highcsharp") == 0)	return 555;
	else if(strcmp(note, "highdflat") == 0)		return 555;
	else if(strcmp(note, "highd") == 0)			return 587;
	else if(strcmp(note, "highdsharp") == 0)	return 623;
	else if(strcmp(note, "higheflat") == 0)		return 623;
	else if(strcmp(note, "highe") == 0)			return 660;
	else if(strcmp(note, "highf") == 0)			return 699;
	else if(strcmp(note, "highfsharp") == 0)	return 740;
	else if(strcmp(note, "highgflat") == 0)		return 740;
	else if(strcmp(note, "highg") == 0)			return 784;
	else if(strcmp(note, "highgsharp") == 0)	return 831;
	else if(strcmp(note, "highaflat") == 0)		return 831;
	else if(strcmp(note, "higha") == 0)			return 880;
	else if(strcmp(note, "highasharp") == 0)	return 924;
	else if(strcmp(note, "highbflat") == 0)		return 924;
	else if(strcmp(note, "highb") == 0)			return 988;
	else if(strcmp(note, "highhighc") == 0)		return 1047;
	else if(strcmp(note, "pause") == 0)			return 0;
	else 										return 3520;
	
}

// beeper is connected to pin 15 which is PB1
void EnableSounds()
{
	DDRB |= 1<<PB1;		// set pin 15 to output
	
	TCCR1A = (1<<COM1A0) | (1<<WGM10);
	TCCR1B = (1<<WGM13) | (1<<CS10);
	OCR1A  = 0;
}

void PlayToneNum(uint16_t frequency, uint16_t duration)
{	
	if (frequency != 0)
	{
		OCR1A = 8000000/frequency;
	}
	delay2(duration);
	OCR1A  = 0;
}

void PlayToneNote(char *note, int duration)
{
	uint16_t frequency = musicNote(note);	
	if (frequency != 0)
	{
		OCR1A = 8000000/frequency;
	}
	delay2(duration);
	OCR1A  = 0;
}

void playSound(char **note, int *duration, int length)
{
	int i = 0;
	int currentDuration = 0;
	char *frequency;
	
	while (i < length)
	{
		frequency = note[i];
		currentDuration = duration[i];
		PlayToneNote(frequency, currentDuration);
		i++;
	}
}
